﻿using System;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Silvermoon.Windows;
using System.Drawing;
using Silvermoon.Images;
using Silvermoon.Windows.Styles;
using Silvermoon.UI;
using System.Globalization;

namespace Testing.Pages
{
    /// <summary>
    /// Shows a list of dates of a year in a listview and groups them by month.
    /// This example illustrates how to use ListView control together with ListViewController class and to remove and add items to the list.
    /// </summary>
    public class ListViewPage : DemoWindowBase
    {
        private readonly Command DeleteCommand = new Command();
        private readonly Command AddCommand = new Command();

        protected ListView listView;
        protected ListViewController<TextItem, DateTime> listViewController;
        private List<DateTime> list;
        private ContextMenu itemMenu;


        public ListViewPage()
            : base()
        {
            InitializePage();
            listViewController.DataSource = CreateItemsSource();
        }

        protected override void Dispose(bool dispose)
        {
            DisposeObject(itemMenu);
            base.Dispose(dispose);
        }

        protected virtual void InitializePage()
        {
            Title = "LISTVIEW DEMO";
            SetTransition(350, TransitionMask.Fade | TransitionMask.Zoom, TransitionMask.Fade | TransitionMask.Explode);
            listView = new ListView { Margin = Margin.Zero, AlwaysShowGroupHeader = true };
            Controls.Add(listView);

            // create the controller which maintance virtual items:
            listViewController = new ListViewController<TextItem, DateTime>(listView);
            listViewController.InitializeItem += new EventHandler<ItemControlGeneratorEventArgs<TextItem>>(OnInitializeItem);
            listViewController.UpdateItem += new EventHandler<ItemControlGeneratorEventArgs<TextItem>>(OnUpdateItem);
            listViewController.GetDescriptorFromValue += new EventHandler<GroupDescriptorEventArgs<DateTime>>(OnGetDescriptorFromValue);
            listViewController.GroupButtonSize = new Size(400, 80);
            listViewController.GroupButtonStyle = new ButtonStyle { Margin = Margin.Zero };
            listViewController.ItemStyle = new TextItemStyle { Font = FontPool.ItemFont };
            listViewController.ItemHeight = 80;

            itemMenu = new ContextMenu(
                new MenuItem { Text = "Delete", Command = DeleteCommand },
                new MenuItem { Text = "Add", Command = AddCommand }
                );

            CreateGroupDescriptors();

        }

        /// <summary>
        /// Creates group descriptors for the ListViewController to enable grouping in a ListView.
        /// </summary>
        private void CreateGroupDescriptors()
        {
            string year = " " + DateTime.Now.Year.ToString();
            foreach (string month in CultureInfo.CurrentUICulture.DateTimeFormat.MonthNames)
            {
                listViewController.GroupDescriptors.Add(new ItemGroupDescriptor<DateTime>(month + year));
            }
        }

        /// <summary>
        /// This method occurs when the ListViewController initializes a newly created item control.
        /// </summary>
        void OnInitializeItem(object sender, ItemControlGeneratorEventArgs<TextItem> e)
        {
            e.Item.ContextMenu = itemMenu;
            e.Item.CommandRaised += new EventHandler<CommandEventArgs>(OnItemCommandRaised);
        }

        /// <summary>
        /// This method occurs when the ListViewController needs to determine a descriptor for an item value.
        /// </summary>
        private void OnGetDescriptorFromValue(object sender, GroupDescriptorEventArgs<DateTime> e)
        {
            int month = e.Value.Month - 1;
            e.Descriptor = e.GroupDescriptors[month];
        }

        /// <summary>
        /// This method occurs when the ListViewController needs to update an item control with the data value.
        /// </summary>
        protected virtual void OnUpdateItem(object sender, ItemControlGeneratorEventArgs<TextItem> e)
        {
            var item = e.Item;
            DateTime date = (DateTime)e.Value;
            item.Text = date.DayOfWeek.ToString() + ", " + date.Day.ToString() + " " + date.ToShortTimeString();
            item.TextColor = date.DayOfWeek == DayOfWeek.Sunday ? PhoneColors.Orange : PhoneColors.Empty;
        }

        void OnItemCommandRaised(object sender, CommandEventArgs e)
        {
            if (e.Command == DeleteCommand)
            {
                RemoveItem(sender);
                e.Handled=true;
            }
            else if (e.Command == AddCommand)
            {
                AddItem(sender);
            }
        }


        /// <summary>
        /// Adds a value to the ListView.
        /// Note that the ListViewController determines the location of the new value using the ValueComparer delegate.
        /// </summary>
        private void AddItem(object sender)
        {
            Item item = sender as Item;
            DateTime date = (DateTime)item.DataValue;
            date = date.AddHours(4);
            listViewController.AddValue(date);
        }

        /// <summary>
        /// Removes a value from the ListView.
        /// </summary>
        private void RemoveItem(object sender)
        {
            Item item = sender as Item;
            listViewController.RemoveValue((DateTime)item.DataValue);
        }

        protected override void OnShown()
        {
            base.OnShown();
            Screen.Progress();
//            listViewController.DataSource = CreateItemsSource();

            // ValueComparer is required to determine the location of a new value to add, and orders the items within a group.
            // but since the list is already ordererd, this delegate is added after the data source is set, to prevent unnecassary sorting.
            listViewController.ValueComparer = (x, y) => x.CompareTo(y);
        }

        private IList<DateTime> CreateItemsSource()
        {
            list = new List<DateTime>(365);
            int year = DateTime.Now.Year;
            DateTime date = new DateTime(year, 1, 1);
            while (date.Year == year)
            {
                list.Add(date);
                date = date.AddDays(1);
            }

            return list;
        }
    }
}
